/*
 * Copyright 2016 Hannes Dorfmann.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package com.hannesdorfmann.mosby3.sample.mvi.view.home;

import io.reactivex.Observable;

import ohos.agp.components.Component;
import ohos.agp.components.LayoutScatter;
import ohos.agp.components.ListContainer;
import ohos.agp.components.TableLayoutManager;
import ohos.agp.components.Text;
import ohos.agp.window.dialog.ToastDialog;
import ohos.app.Context;

import com.hannesdorfmann.mosby3.mvi.MviFraction;
import com.hannesdorfmann.mosby3.sample.mvi.MyApplication;
import com.hannesdorfmann.mosby3.sample.mvi.ResourceTable;
import com.hannesdorfmann.mosby3.sample.mvi.businesslogic.model.Product;
import com.hannesdorfmann.mosby3.sample.mvi.view.detail.ProductDetailsAbility;
import com.hannesdorfmann.mosby3.sample.mvi.view.ui.viewholder.ProductViewHolder;
import com.hannesdorfmann.mosby3.sample.mvi.view.widge.CirleProgressImg;
import com.hannesdorfmann.swiperefresh.refresh.IRefresh;
import com.hannesdorfmann.swiperefresh.refresh.SwipeRefreshLayout;
import com.hannesdorfmann.swiperefresh.refresh.TextOverComponent;
import com.jakewharton.rxbinding2.widget.RxListContainer;
import com.jakewharton.rxbinding2.widget.RxSwipeRefreshLayout;

/**
 * @author Hannes Dorfmann
 */

public class HomeFraction extends MviFraction<HomeView, HomePresenter>
        implements HomeView, ProductViewHolder.ProductClickedListener {

    private HomeAdapter adapter;

    SwipeRefreshLayout swipeRefreshLayout;
    ListContainer listContainer;
    CirleProgressImg loadingView;
    Text errorView;
    int spanCount = 2;
    IRefresh.RefreshListener refreshListener;
    TableLayoutManager layoutManager;

    Context context;

    public HomeFraction(Context context) {
        this.context = context;
    }

    @Override
    protected int getUIContent() {
        return ResourceTable.Layout_fragment_home;
    }

    @Override
    protected void initCompoment() {
        swipeRefreshLayout = (SwipeRefreshLayout) mComponent.findComponentById(ResourceTable.Id_swipeRefreshLayout);
        listContainer = (ListContainer) mComponent.findComponentById(ResourceTable.Id_listContainer);
        loadingView = (CirleProgressImg) mComponent.findComponentById(ResourceTable.Id_loadingView);
        errorView = (Text) mComponent.findComponentById(ResourceTable.Id_errorView);

        // 创建下拉刷新头部组件
        TextOverComponent overView = new TextOverComponent(context);
        // 设置下拉刷新的头部组件
        swipeRefreshLayout.setRefreshOverComponent(overView);
        refreshListener = new IRefresh.RefreshListener() {
            @Override
            public void onRefresh() {
                loadFirstPageIntent();
            }

            @Override
            public boolean enableRefresh() {
                return true;
            }
        };
        swipeRefreshLayout.setRefreshListener(refreshListener);

        adapter = new HomeAdapter(LayoutScatter.getInstance(context), this);
        listContainer.setItemProvider(adapter);
//    layoutManager = new TableLayoutManager();
//    layoutManager.setColumnCount(spanCount);
//    listContainer.setLayoutManager(layoutManager);

//    layoutManager = new GridLayoutManager(getActivity(), spanCount);
//    layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
//      @Override public int getSpanSize(int position) {
//
//        int viewType = adapter.getItemViewType(position);
//        if (viewType == HomeAdapter.VIEW_TYPE_LOADING_MORE_NEXT_PAGE
//                || viewType == HomeAdapter.VIEW_TYPE_SECTION_HEADER) {
//          return spanCount;
//        }
//
//        return 1;
//      }
//    });

    }

    @Override
    public HomePresenter createPresenter() {
        return MyApplication.getDependencyInjection(context).newHomePresenter();
    }

    @Override
    public void onProductClicked(Product product) {
        ProductDetailsAbility.start(getFractionAbility(), product);
    }

    @Override
    public Observable<Boolean> loadFirstPageIntent() {
        return Observable.just(true);
    }

    @Override
    public Observable<Boolean> loadNextPageIntent() {
        return RxListContainer.scrollEvents(listContainer)
                .filter(event -> !adapter.isLoadingNextPage())
//            .filter(event -> event == RecyclerView.SCROLL_STATE_IDLE)
//            .filter(event -> layoutManager.findLastCompletelyVisibleItemPosition()
//                    == adapter.getItems().size() - 1)
                .map(integer -> true);
    }

    @Override
    public Observable<Boolean> pullToRefreshIntent() {
        return RxSwipeRefreshLayout.refreshes(swipeRefreshLayout).map(ignored -> true);
    }

    @Override
    public Observable<String> loadAllProductsFromCategoryIntent() {
        return adapter.loadMoreItemsOfCategoryObservable();
    }

    @Override
    public void render(HomeViewState viewState) {
        swipeRefreshLayout.refreshFinish();
        if (!viewState.isLoadingFirstPage() && viewState.getFirstPageError() == null) {
            renderShowData(viewState);
        } else if (viewState.isLoadingFirstPage()) {
            renderFirstPageLoading();
        } else if (viewState.getFirstPageError() != null) {
            renderFirstPageError();
        } else {
            throw new IllegalStateException("Unknown view state " + viewState);
        }
    }

    private void renderShowData(HomeViewState state) {
        loadingView.setVisibility(Component.HIDE);
        errorView.setVisibility(Component.HIDE);
        swipeRefreshLayout.setVisibility(Component.VISIBLE);
        boolean changed = adapter.setLoadingNextPage(state.isLoadingNextPage());
        adapter.setItems(state.getData()); // TODO error: this must be done before setLoading() otherwise error will occure. see https://github.com/sockeqwe/mosby/issues/244

        boolean enableRfresh = refreshListener.enableRefresh();
        swipeRefreshLayout.setRefreshing(state.isLoadingPullToRefresh());

        if (state.getPullToRefreshError() != null) {
            String errMsg = "";
            try {
                errMsg = getResourceManager().getElement(ResourceTable.String_error_unknown).getString();
            } catch (Exception e) {
                System.err.println("err e:" + e.getMessage());
            }

            ToastDialog toastDialog = new ToastDialog(getFractionAbility());
            toastDialog.setText(errMsg);
            toastDialog.show();

        }
    }

    private void renderFirstPageLoading() {
        loadingView.setVisibility(Component.VISIBLE);
        errorView.setVisibility(Component.HIDE);
        swipeRefreshLayout.setVisibility(Component.HIDE);
    }

    private void renderFirstPageError() {
    loadingView.setVisibility(Component.HIDE);
    swipeRefreshLayout.setVisibility(Component.HIDE);
    errorView.setVisibility(Component.VISIBLE);
  }
}
